package org.jeecg.modules.storage.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.BeanPlusUtil;
import org.jeecg.modules.erp.base.entity.ErpLocation;
import org.jeecg.modules.erp.base.entity.ErpWarehouse;
import org.jeecg.modules.erp.base.mapper.ErpLocationMapper;
import org.jeecg.modules.erp.base.service.IErpWarehouseService;
import org.jeecg.modules.flowable.apithird.business.entity.FlowMyBusiness;
import org.jeecg.modules.flowable.apithird.business.mapper.FlowMyBusinessMapper;
import org.jeecg.modules.flowable.apithird.service.FlowCallBackServiceI;
import org.jeecg.modules.flowable.apithird.service.FlowCommonService;
import org.jeecg.modules.flowable.service.IFlowDefinitionService;
import org.jeecg.modules.inventory.entity.BussInventoryDetails;
import org.jeecg.modules.inventory.entity.BussInventoryInoutDetails;
import org.jeecg.modules.inventory.entity.BussInventoryPurchaseOrder;
import org.jeecg.modules.inventory.mapper.BussInventoryDetailsMapper;
import org.jeecg.modules.inventory.mapper.BussInventoryInoutDetailsMapper;
import org.jeecg.modules.inventory.mapper.BussInventoryMapper;
import org.jeecg.modules.inventory.mapper.BussInventoryPurchaseOrderMapper;
import org.jeecg.modules.inventory.service.IBussInventoryDetailsService;
import org.jeecg.modules.inventory.service.IBussInventoryInoutDetailsService;
import org.jeecg.modules.inventory.service.IBussInventoryPurchaseOrderService;
import org.jeecg.modules.outbound.entity.BussOutboundOrderDetail;
import org.jeecg.modules.outbound.mapper.BussOutboundOrderDetailMapper;
import org.jeecg.modules.procurement.entity.BussMaterialProcurement;
import org.jeecg.modules.procurement.entity.BussMaterialProcurementDetail;
import org.jeecg.modules.procurement.mapper.BussMaterialProcurementDetailMapper;
import org.jeecg.modules.procurement.mapper.BussMaterialProcurementMapper;
import org.jeecg.modules.storage.entity.BussStorageNotice;
import org.jeecg.modules.storage.entity.BussStorageNoticeCarinfo;
import org.jeecg.modules.storage.entity.BussStorageNoticeMaterial;
import org.jeecg.modules.storage.mapper.BussStorageNoticeCarinfoMapper;
import org.jeecg.modules.storage.mapper.BussStorageNoticeMapper;
import org.jeecg.modules.storage.mapper.BussStorageNoticeMaterialMapper;
import org.jeecg.modules.storage.service.IBussStorageNoticeCarinfoService;
import org.jeecg.modules.storage.service.IBussStorageNoticeMaterialService;
import org.jeecg.modules.storage.service.IBussStorageNoticeService;
import org.jeecg.modules.storage.service.IProcurementManagementService;
import org.jeecg.modules.storage.vo.BussStorageNoticeMaterialVo;
import org.jeecg.modules.storage.vo.BussStorageNoticePage;
import org.jeecg.modules.storage.vo.StoragePage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static org.jeecg.modules.constant.Constant.*;
import static org.jeecg.modules.constant.TypeConstant.*;

/**
 * @Description: 入库通知单
 * @Author: jeecg-boot
 * @Date: 2024-06-18
 * @Version: V1.0
 */
@Service("bussStorageNoticeServiceImpl")
public class BussStorageNoticeServiceImpl extends ServiceImpl<BussStorageNoticeMapper, BussStorageNotice> implements IBussStorageNoticeService, FlowCallBackServiceI {

    @Autowired
    private BussStorageNoticeMapper bussStorageNoticeMapper;
    @Autowired
    private BussStorageNoticeCarinfoMapper bussStorageNoticeCarinfoMapper;
    @Autowired
    private IBussStorageNoticeCarinfoService iBussStorageNoticeCarinfoService;
    @Autowired
    private BussStorageNoticeMaterialMapper bussStorageNoticeMaterialMapper;
    @Autowired
    private IBussStorageNoticeMaterialService iBussStorageNoticeMaterialService;
    @Autowired
    private BussInventoryMapper bussInventoryMapper;
    @Autowired
    private BussMaterialProcurementDetailMapper bussMaterialProcurementDetailMapper;
    @Autowired
    private BussInventoryPurchaseOrderMapper bussInventoryPurchaseOrderMapper;
    @Autowired
    private IBussInventoryPurchaseOrderService iBussInventoryPurchaseOrderService;
    @Autowired
    private BussMaterialProcurementMapper bussMaterialProcurementMapper;
    @Autowired
    private IErpWarehouseService erpWarehouseService;

    @Autowired
    FlowCommonService flowCommonService;

    @Autowired
    private ErpLocationMapper erpLocationMapper;

    @Autowired
    private IProcurementManagementService iProcurementManagementService;

    @Override
    public void afterFlowHandle(FlowMyBusiness business) {
        //流程操作后做些什么
        business.getTaskNameId();//接下来审批的节点
        business.getValues();//前端传进来的参数
        String actStatus = business.getActStatus();//流程状态 ActStatus.java
        String dataId = business.getDataId();
        BussStorageNotice bussStorageNotice = bussStorageNoticeMapper.selectById(dataId);
        if (ObjectUtil.isNotEmpty(bussStorageNotice)) {
            if ("审批通过".equals(actStatus)) {
                // 审批通过
                bussStorageNotice.setStatus("3");
                bussStorageNoticeMapper.updateById(bussStorageNotice);
            } else if ("启动".equals(actStatus)) {
                bussStorageNotice.setStatus("1");
                bussStorageNoticeMapper.updateById(bussStorageNotice);
            } else if ("审批中".equals(actStatus)) {
                bussStorageNotice.setStatus("1");
                bussStorageNoticeMapper.updateById(bussStorageNotice);
            } else if ("撤回".equals(actStatus) || "驳回".equals(actStatus)) {
                bussStorageNotice.setStatus("2");
                bussStorageNoticeMapper.updateById(bussStorageNotice);
            }
        }

        //....其他
    }


    @Override
    public Object getBusinessDataById(String dataId) {
        return this.getById(dataId);
    }

    @Override
    public Map<String, Object> flowValuesOfTask(String taskNameId, Map<String, Object> values) {
        return null;
    }

    @Override
    public List<String> flowCandidateUsernamesOfTask(String taskNameId, Map<String, Object> values) {
        // 通过当前节点来判断下一个节点的候选人并写回到反参中，如果为null，流程模块会根据默认设置处理

        return null;
    }

    @Override
    public IPage<BussStorageNoticePage> myPage(Page<BussStorageNoticePage> page, QueryWrapper<BussStorageNoticePage> queryWrapper) {
        return this.baseMapper.myPage(page, queryWrapper);
    }

    @Override
    public IPage<BussStorageNoticePage> exportList(Page<BussStorageNoticePage> page, QueryWrapper<BussStorageNoticePage> queryWrapper) {
        return this.baseMapper.exportList(page, queryWrapper);
    }


    //	@Override
//	public boolean save(BussStorageNotice bussStorageNotice) {
//		/**新增数据**/
//		bussStorageNotice.setId(IdUtil.fastSimpleUUID());
//		//Comparison method violates its general contract!有时候出现这个错误加的，原因不明
//		System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
//		return super.save(bussStorageNotice);
//	}
    @Override
    public boolean removeById(Serializable id) {
        /**删除数据，移除流程关联信息**/
        flowCommonService.delActBusiness(id.toString());
        return super.removeById(id);
    }


    @Override
    public IPage<BussStorageNoticePage> pagelist(IPage<BussStorageNoticePage> page, QueryWrapper<BussStorageNoticePage> queryWrapper) {
        return bussStorageNoticeMapper.pageList(page, queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMain(BussStorageNotice bussStorageNotice, List<BussStorageNoticeCarinfo> bussStorageNoticeCarinfoList, List<BussStorageNoticeMaterial> bussStorageNoticeMaterialList) {
        if (bussStorageNotice.getStorageType().equals(INPUT_TYPE_GARBAGE)) {
            // 废旧物直接入库
            bussStorageNotice.setStatus("2");
        }
        bussStorageNoticeMapper.insert(bussStorageNotice);

        /**
         * 添加物料收货信息
         */
        if (bussStorageNoticeMaterialList != null && bussStorageNoticeMaterialList.size() > 0) {
            List<BussStorageNoticeMaterial> list = new ArrayList<>();
            for (BussStorageNoticeMaterial entity : bussStorageNoticeMaterialList) {
                //外键设置
                entity.setNoticeId(bussStorageNotice.getId());
                entity.setNoticeCode(bussStorageNotice.getCode());
                entity.setParentLogtime(bussStorageNotice.getLogtime());
                if (bussStorageNotice.getStorageType().equals(INPUT_TYPE_GARBAGE)) {
                    // 废旧物直接合格
                    entity.setQcStatus(QUALITY_INSPECTION_STATUS_PASS);
                }
                if (!StringUtils.isEmpty(entity.getProcurementDetailId())) {
                    iProcurementManagementService.addNumProcurementAtNotice(entity);
                }
                list.add(entity);
            }
            iBussStorageNoticeMaterialService.saveBatch(list);

        }

        /**
         * 添加车辆信息
         */
        if (bussStorageNoticeCarinfoList != null && bussStorageNoticeCarinfoList.size() > 0) {
            List<BussStorageNoticeCarinfo> bussStorageNoticeCarinfos = new ArrayList<>();
            for (BussStorageNoticeCarinfo entity : bussStorageNoticeCarinfoList) {
                //外键设置
                entity.setNoticeId(bussStorageNotice.getId());
                bussStorageNoticeCarinfos.add(entity);
//                bussStorageNoticeCarinfoMapper.insert(entity);
            }
            iBussStorageNoticeCarinfoService.saveBatch(bussStorageNoticeCarinfos);
        }

        saveInventory(bussStorageNotice, bussStorageNoticeMaterialList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMain(BussStorageNotice bussStorageNotice, List<BussStorageNoticeCarinfo> bussStorageNoticeCarinfoList, List<BussStorageNoticeMaterial> bussStorageNoticeMaterialList) {
        BussStorageNotice noticeSource = bussStorageNoticeMapper.selectById(bussStorageNotice.getId());
        if (noticeSource.getStatus().equals("0") || noticeSource.getStatus().equals("2")) {
            throw new RuntimeException("入库单已审批，或已入库暂时无法修改");
        }
        this.checkRetract(bussStorageNotice.getId());
        bussStorageNotice.setStatus("0");//已审批
        if (bussStorageNotice.getStorageType().equals("1")) {
            bussStorageNotice.setStatus("2");
        }
        if (bussStorageNotice.getStorageType().equals("3")) {
//			this.updateProcurementDetail(bussStorageNotice.getId());
            List<BussStorageNoticeMaterial> list = this.bussStorageNoticeMaterialMapper
                    .selectList(new LambdaQueryWrapper<BussStorageNoticeMaterial>().eq(BussStorageNoticeMaterial::getNoticeId, bussStorageNotice.getId())
                            .select(BussStorageNoticeMaterial::getProcurementDetailId, BussStorageNoticeMaterial::getActualNum, BussStorageNoticeMaterial::getId));
            this.iProcurementManagementService.subtractNumProcurementAtNotice(list);
        }
        bussStorageNoticeMapper.updateById(bussStorageNotice);
        //1.先删除子表数据
        //删除前恢复库存数量，删除入库记录
//		quantityRefund(bussStorageNotice.getId());
        bussStorageNoticeCarinfoMapper.deleteByMainId(bussStorageNotice.getId());
        bussStorageNoticeMaterialMapper.deleteByMainId(bussStorageNotice.getId());
        //2.子表数据重新插入
        if (!CollectionUtils.isEmpty(bussStorageNoticeCarinfoList)) {
            for (BussStorageNoticeCarinfo entity : bussStorageNoticeCarinfoList) {
                //外键设置
                entity.setNoticeId(bussStorageNotice.getId());
                bussStorageNoticeCarinfoMapper.insert(entity);
            }
        }
        if (!CollectionUtils.isEmpty(bussStorageNoticeMaterialList)) {
            for (BussStorageNoticeMaterial entity : bussStorageNoticeMaterialList) {
                entity.setStatus(0);
                //外键设置
                entity.setNoticeCode(bussStorageNotice.getCode());
                entity.setNoticeId(bussStorageNotice.getId());
                entity.setParentLogtime(bussStorageNotice.getLogtime());
                if (bussStorageNotice.getStorageType().equals("1")) {
                    // 废旧物直接合格
                    entity.setQcStatus("1");
                }
                if (!StringUtils.isEmpty(entity.getProcurementDetailId())) {
                    this.iProcurementManagementService.addNumProcurementAtNotice(entity);
                }
                bussStorageNoticeMaterialMapper.insert(entity);
                //this.updateProcurementDetail(entity);
            }
        }
        this.deleteInventoryDetails(bussStorageNotice.getId());
        this.saveInventory(bussStorageNotice, bussStorageNoticeMaterialList);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delBatchMain(Collection<? extends String> idList) {
        for (String id : idList) {
            this.deleteData(id);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteMain(String id) {
        this.checkRetract(id);
        List<BussStorageNoticeMaterial> bussStorageNoticeMaterials = bussStorageNoticeMaterialMapper.selectList(new LambdaQueryWrapper<BussStorageNoticeMaterial>().select(BussStorageNoticeMaterial::getId).eq(BussStorageNoticeMaterial::getNoticeId, id));
        List<String> collect = bussStorageNoticeMaterials.stream().map(BussStorageNoticeMaterial::getId).collect(Collectors.toList());
        this.delBatchMain(collect);
    }

    /**
     * 删除物料明细数据
     *
     * @param detailId
     */
    private void deleteData(String detailId) {
        BussStorageNoticeMaterial bussStorageNoticeMaterial = bussStorageNoticeMaterialMapper.selectById(detailId);
        BussStorageNotice bussStorageNotice = bussStorageNoticeMapper.selectById(bussStorageNoticeMaterial.getNoticeId());
        if (bussStorageNotice.getStatus().equals(0) || bussStorageNotice.getStatus().equals(2)) {
            throw new RuntimeException("入库单已审批或已入库！");
        }
        if (!bussStorageNoticeMaterial.getQcStatus().equals("0") && !bussStorageNotice.getStorageType().equals("1")) { //排除废旧物入库
            throw new RuntimeException("已质检无法删除！");
        }
        // 查询是否出库-等待出库明细添加入库明细id
        Long outCount = bussOutboundOrderDetailMapper.selectCount(new LambdaQueryWrapper<BussOutboundOrderDetail>()
                .eq(BussOutboundOrderDetail::getStorageMaterialId, detailId));
        if (outCount > 0) {
            throw new RuntimeException("已出库无法删除！");
        }
        //删除前恢复库存数量，删除入库记录
//		quantityRefund(bussStorageNotice.getId());
        bussStorageNoticeMaterialMapper.deleteById(bussStorageNoticeMaterial);
        bussStorageNoticeCarinfoMapper.delete(new LambdaQueryWrapper<BussStorageNoticeCarinfo>()
                .eq(BussStorageNoticeCarinfo::getRowNum, bussStorageNoticeMaterial.getRowNum()).eq(BussStorageNoticeCarinfo::getMaterialId, bussStorageNoticeMaterial.getMaterialId()));
        Long aLong = bussStorageNoticeMaterialMapper.selectCount(new LambdaQueryWrapper<BussStorageNoticeMaterial>()
                .eq(BussStorageNoticeMaterial::getNoticeId, bussStorageNoticeMaterial.getNoticeId()));
        if (aLong == 0) {
            String noticeId = bussStorageNoticeMaterial.getNoticeId();
            bussStorageNoticeMapper.deleteById(noticeId);
            /**删除数据，移除流程关联信息**/
//			flowCommonService.delActBusiness(noticeId);
        }
//		this.updateProcurementDetail(bussStorageNoticeMaterial);
        if (!StringUtils.isEmpty(bussStorageNoticeMaterial.getProcurementDetailId())) {
            List<BussStorageNoticeMaterial> list = new ArrayList<>();
            list.add(bussStorageNoticeMaterial);
            iProcurementManagementService.subtractNumProcurementAtNotice(list);
        }
        this.deleteInventoryDetail(detailId);
    }

    /**
     * 删除库存明细
     *
     * @param id 主表id
     */
    private void deleteInventoryDetails(String id) {
        List<BussStorageNoticeMaterial> bussStorageNoticeMaterials = this.bussStorageNoticeMaterialMapper.selectList(new LambdaQueryWrapper<BussStorageNoticeMaterial>().select(BussStorageNoticeMaterial::getId).eq(BussStorageNoticeMaterial::getNoticeId, id));
        bussStorageNoticeMaterials.stream().forEach(item -> this.deleteInventoryDetail(item.getId()));
    }


    /**
     * 删除库存明细
     */
    private void deleteInventoryDetail(String detailId) {
        // 删除明细数据
        this.bussInventoryDetailsMapper.delete(new LambdaQueryWrapper<BussInventoryDetails>()
                .eq(BussInventoryDetails::getInventoryId, detailId));
    }


    /**
     * 修改采购订单状态，删除之前调用
     *
     * @param noticeId
     */
    private void updateProcurementDetail(String noticeId) {
        List<BussStorageNoticeMaterial> bussStorageNoticeMaterials = bussStorageNoticeMaterialMapper
                .selectList(new LambdaQueryWrapper<BussStorageNoticeMaterial>()
                        .select(BussStorageNoticeMaterial::getProcurementDetailId, BussStorageNoticeMaterial::getActualNum)
                        .eq(BussStorageNoticeMaterial::getNoticeId, noticeId));
        for (BussStorageNoticeMaterial bussStorageNoticeMaterial : bussStorageNoticeMaterials) {
            String procurementDetailId = bussStorageNoticeMaterial.getProcurementDetailId();
            BussMaterialProcurementDetail bussMaterialProcurementDetail = bussMaterialProcurementDetailMapper.selectById(procurementDetailId);
            if (bussMaterialProcurementDetail == null) {
                return;
            }
            bussMaterialProcurementDetail.setArrivalNum(bussMaterialProcurementDetail.getArrivalNum().subtract(bussStorageNoticeMaterial.getActualNum()));
            bussMaterialProcurementDetailMapper.update(bussMaterialProcurementDetail, new LambdaUpdateWrapper<BussMaterialProcurementDetail>()
                    .eq(BussMaterialProcurementDetail::getId, procurementDetailId).set(BussMaterialProcurementDetail::getStatus, 2));
        }
    }


    /**
     * 修改采购明细单状态
     *
     * @param
     */
    private void updateProcurementDetail(BussStorageNoticeMaterial bussStorageNoticeMaterial) {
        if (StringUtils.isEmpty(bussStorageNoticeMaterial.getProcurementDetailId())) {
            return;
        }
        BussMaterialProcurementDetail bussMaterialProcurementDetail = bussMaterialProcurementDetailMapper.selectById(bussStorageNoticeMaterial.getProcurementDetailId());
        List<BussStorageNoticeMaterial> bussStorageNoticeMaterials = bussStorageNoticeMaterialMapper.selectList(new LambdaQueryWrapper<BussStorageNoticeMaterial>()
                .select(BussStorageNoticeMaterial::getMaterialId, BussStorageNoticeMaterial::getActualNum)
                .eq(BussStorageNoticeMaterial::getProcurementDetailId, bussStorageNoticeMaterial.getProcurementDetailId()));
        if (CollectionUtils.isEmpty(bussStorageNoticeMaterials)) {
            bussMaterialProcurementDetail.setStatus(0);
            bussMaterialProcurementDetailMapper.updateById(bussMaterialProcurementDetail);
            return;
        }
        BigDecimal reduce = this.getAllActualNum(bussStorageNoticeMaterial.getProcurementDetailId());
        if (reduce.compareTo(bussMaterialProcurementDetail.getProcurementNum()) > 0) {
            throw new RuntimeException("入库单数量不能大于采购数量");
        } else if (reduce.compareTo(bussMaterialProcurementDetail.getProcurementNum()) < 0) {
            bussMaterialProcurementDetail.setStatus(2);
        } else if (reduce.compareTo(bussMaterialProcurementDetail.getProcurementNum()) == 0) {
            bussMaterialProcurementDetail.setStatus(1);
        }
        bussMaterialProcurementDetail.setArrivalNum(reduce);
        bussMaterialProcurementDetailMapper.updateById(bussMaterialProcurementDetail);
    }

    @Autowired
    private IFlowDefinitionService flowDefinitionService;

    @Autowired
    private FlowMyBusinessMapper flowMyBusinessMapper;


    @Autowired
    private IBussStorageNoticeCarinfoService bussStorageNoticeCarinfoService;
    @Autowired
    private IBussStorageNoticeMaterialService bussStorageNoticeMaterialService;

    @Override
    public Result reverseCheck(String id) {
        BussStorageNotice bussStorageNotice = this.getById(id);
        if (bussStorageNotice == null) {
            return Result.error("未找到对应数据");
        }
        bussStorageNotice.setDisuse(1);
        this.updateById(bussStorageNotice);
        BussStorageNotice copyDes = new BussStorageNotice();
        BeanUtils.copyProperties(bussStorageNotice, copyDes, "createTime", "updateTime", "updateBy", "createBy", "id", "disuse");
        copyDes.setStatus("2");
        this.save(copyDes);
        String dataId = copyDes.getId();
        //todo 子表相关信息 添加
        List<BussStorageNoticeMaterialVo> bussStorageNoticeMaterialVos = bussStorageNoticeMaterialService.selectByMainId(bussStorageNotice.getId());
        List<BussStorageNoticeMaterial> bussStorageNoticeMaterials = BeanPlusUtil.toBeanList(bussStorageNoticeMaterialVos, BussStorageNoticeMaterial.class, "createTime", "updateTime", "updateBy", "createBy", "noticeId", "id");
        bussStorageNoticeMaterials.stream().forEach(item -> item.setNoticeId(dataId));
        bussStorageNoticeMaterialService.saveBatch(bussStorageNoticeMaterials);
        List<BussStorageNoticeCarinfo> bussStorageNoticeCarinfos = BeanPlusUtil.toBeanList(bussStorageNoticeCarinfoService.selectByMainId(bussStorageNotice.getId()), BussStorageNoticeCarinfo.class, "createTime", "updateTime", "updateBy", "createBy", "noticeId", "id");
        bussStorageNoticeCarinfos.stream().forEach(item -> item.setNoticeId(dataId));
        bussStorageNoticeCarinfoService.saveBatch(bussStorageNoticeCarinfos);

        BeanMap variables = new BeanMap(copyDes);
        FlowMyBusiness flowMyBusiness = flowMyBusinessMapper.selectOne(new LambdaQueryWrapper<FlowMyBusiness>().eq(FlowMyBusiness::getDataId, id).last(" limit 1"));
        if (Objects.isNull(flowMyBusiness)) {
            return Result.error("该表单尚未发起审批,不可以发起反审核操作");
        }
        String actStatus = flowMyBusiness.getActStatus();
        if (!"审批通过".equals(actStatus)) {
            return Result.error("只有审批通过的表单可以发起反审核操作");
        }
        // 转换为 Map<String, Object>
//        Map<String, Object> map = new HashMap<>();
//        for (Object key : variables.keySet()) {
//            map.put((String) key, variables.get(key));
//        }
//        map.put("dataId", dataId);
        this.deleteMain(id);
        return Result.ok("撤销审核成功,发起人可以重新修改表单后提交申请");
//        return flowDefinitionService.startProcessInstanceByDataId(dataId, "bussStorageNoticeServiceImpl", map);
    }

    /**
     * 入库通知单更新库存
     *
     * @param bussStorageNotice
     * @param bussStorageNoticeMaterialList
     */
    public void saveInventory(BussStorageNotice bussStorageNotice, List<BussStorageNoticeMaterial> bussStorageNoticeMaterialList) {
        //新增采购订单集合
        List<BussInventoryPurchaseOrder> bussInventoryPurchaseOrderList = new ArrayList<>();
        //库存明细集合
        List<BussInventoryDetails> bussInventoryDetailsList = new ArrayList<>();
        //生成出入库明细集合
        List<BussInventoryInoutDetails> bussInventoryInoutDetailsList = new ArrayList<>();
        for (BussStorageNoticeMaterial detail : bussStorageNoticeMaterialList) {
            //通过库位找仓库
            ErpWarehouse warehouse = erpWarehouseService.selectByLocation(detail.getErpLocationId());
            ErpLocation erpLocation = erpLocationMapper.selectById(detail.getErpLocationId());

            BussInventoryDetails bussInventoryDetails = new BussInventoryDetails();
            bussInventoryDetails.setInventoryId(detail.getId());
            bussInventoryDetails.setCode(bussStorageNotice.getCode());
            bussInventoryDetails.setMaterialId(detail.getMaterialId());
            bussInventoryDetails.setQuantity(detail.getActualNum());
            bussInventoryDetails.setInventoryQuantity(detail.getActualNum());
            bussInventoryDetails.setStorageId(bussStorageNotice.getId());//赋值入库Id
            //todo 库位，仓库未赋值
//			bussInventoryDetails.setWarehouseLocationCode(detail.getErpLocationId());
            bussInventoryDetails.setWarehouseLocation(detail.getErpLocationId());
            bussInventoryDetails.setWarehouseLocationCode(erpLocation.getCode());
            bussInventoryDetails.setWarehouseCode(warehouse.getCode());
            bussInventoryDetails.setWarehouseName(warehouse.getName());
            bussInventoryDetails.setBatch(detail.getBatchNum());
            bussInventoryDetails.setMaterialBatchNumber(detail.getMaterialLotNum());
            bussInventoryDetails.setInOutDate(detail.getWarehouseDate());
            bussInventoryDetails.setEnterDate(detail.getWarehouseDate());
            bussInventoryDetails.setRestrictedDate(detail.getExpiryDate());
            bussInventoryDetails.setPreparedBy(bussStorageNotice.getCreateBy());
            bussInventoryDetails.setPreparedTime(bussStorageNotice.getCreateTime());
            bussInventoryDetails.setProductionDate(detail.getCreateDate());
            //状态默认正常，质检状态默认待质检
            bussInventoryDetails.setStatus(DATA_STATUS_NORMAL);
            bussInventoryDetails.setQualityInspectionStatus(QUALITY_INSPECTION_STATUS_WAIT_INSPECTION);
            //如果入库类型为废料入库,则质检状态为合格
            if (bussStorageNotice.getStorageType().equals(INPUT_TYPE_GARBAGE)) {
                bussInventoryDetails.setQualityInspectionStatus(QUALITY_INSPECTION_STATUS_PASS);
            }
            //操作类型默认原材料手填入库
            bussInventoryDetails.setOperationCategory(OPERATION_TYPE_MANUAL_OPERATION);
            bussInventoryDetails.setSupplierId(detail.getSupplierId());
            //赋值宝洁信息
            bussInventoryDetails.setBjSupplier(bussStorageNotice.getBjSupplierName());
            bussInventoryDetails.setBjOrder(bussStorageNotice.getBjProcurementCode());
            bussInventoryDetails.setBjSupplierCode(bussStorageNotice.getBjSupplierCode());
            //集合添加库存明细，统一添加
            bussInventoryDetailsList.add(bussInventoryDetails);
//            bussInventoryDetailsMapper.insert(bussInventoryDetails);

            //生成出入库明细
            BussInventoryInoutDetails bussInventoryInoutDetails = new BussInventoryInoutDetails();
            bussInventoryInoutDetails.setOperator(bussStorageNotice.getCreateBy());
            bussInventoryInoutDetails.setOperationTime(bussStorageNotice.getCreateTime());

            //业务默认入库
            bussInventoryInoutDetails.setBusiness(INOUT_BUSINESS_IN);
            // todo
            // 业务类型判断暂时赋值原料入库
            bussInventoryInoutDetails.setBusinessType("1");
            bussInventoryInoutDetails.setQuantity(detail.getActualNum());
            bussInventoryInoutDetails.setBusinessCode(bussStorageNotice.getCode());
            bussInventoryInoutDetails.setBusinessId(bussStorageNotice.getId());
            bussInventoryInoutDetails.setInventoryId(bussInventoryDetails.getInventoryId());
            bussInventoryInoutDetails.setDetailId(bussInventoryDetails.getId());
            bussInventoryInoutDetails.setRemark(detail.getRemark());
            bussInventoryInoutDetailsList.add(bussInventoryInoutDetails);
//            bussInventoryInoutDetailsMapper.insert(bussInventoryInoutDetails);
            //根据采购明细Id找采购订单
            if (StringUtils.isNotEmpty(detail.getProcurementDetailId())) {
                BussMaterialProcurementDetail procurementDetail = bussMaterialProcurementDetailMapper.selectById(detail.getProcurementDetailId());
                if (procurementDetail != null && StringUtils.isNotEmpty(procurementDetail.getProcurementId())) {
                    BussMaterialProcurement procurement = bussMaterialProcurementMapper.selectById(procurementDetail.getProcurementId());
                    if (procurement != null) {
//						bussInventory.setIsHaveOrder("1");
//						bussInventoryMapper.updateById(bussInventory);
                        bussInventoryDetails.setOperationCategory("1");
                        bussInventoryDetailsMapper.updateById(bussInventoryDetails);
                        //判断有没有这条明细对应的关联，有修改数量，没有新增
                        BussInventoryPurchaseOrder order = bussInventoryPurchaseOrderMapper.selectByOrderId(bussInventoryDetails.getId(), procurementDetail.getId());
                        if (order != null) {
                            order.setInStockQuantity(order.getInStockQuantity().add(detail.getActualNum()));
                            bussInventoryPurchaseOrderMapper.updateById(order);
                        } else {
                            //查询订单
                            order = new BussInventoryPurchaseOrder();
                            order.setInventoryId(bussInventoryDetails.getId());
                            order.setInStockQuantity(detail.getActualNum());
                            order.setOrderQuantity(procurement.getNum());
                            order.setPreparedBy(procurement.getCreateBy());
                            order.setPreparedTime(procurement.getCreateTime());
                            order.setOrderId(procurementDetail.getProcurementId());
                            order.setOrderDetailId(procurementDetail.getId());
                            order.setOrderCode(procurement.getCode());
//                            bussInventoryPurchaseOrderMapper.insert(order);
                            bussInventoryPurchaseOrderList.add(order);
                        }
                    }
                }
            }
        }
        iBussInventoryDetailsService.saveBatch(bussInventoryDetailsList);
        iBussInventoryPurchaseOrderService.saveBatch(bussInventoryPurchaseOrderList);
        iBussInventoryInoutDetailsService.saveBatch(bussInventoryInoutDetailsList);
    }

    @Override
    public void checkProcMaterialNum(BussStorageNoticeMaterialVo vo) {
        BigDecimal allActualNum = this.getAllActualNum(vo.getProcurementDetailId());
        if (!StringUtils.isEmpty(vo.getId())) {
            BussStorageNoticeMaterial bussStorageNoticeMaterial = bussStorageNoticeMaterialMapper.selectById(vo.getId());
            allActualNum = allActualNum.subtract(bussStorageNoticeMaterial.getActualNum());
        }
        allActualNum = allActualNum.add(vo.getActualNum());
        BussMaterialProcurementDetail bussMaterialProcurementDetail = bussMaterialProcurementDetailMapper.selectById(vo.getProcurementDetailId());
        if (bussMaterialProcurementDetail.getProcurementNum().compareTo(allActualNum) < 0) {
            throw new RuntimeException("入库数量不能大于采购数量!");
        }
    }

    /**
     * 获取所有到货数量
     *
     * @param procurementDetailId
     * @return
     */
    private BigDecimal getAllActualNum(String procurementDetailId) {
        List<BussStorageNoticeMaterial> bussStorageNoticeMaterials = bussStorageNoticeMaterialMapper.selectList(new LambdaQueryWrapper<BussStorageNoticeMaterial>()
                .select(BussStorageNoticeMaterial::getActualNum)
                .eq(BussStorageNoticeMaterial::getProcurementDetailId, procurementDetailId));
        BigDecimal reduce = bussStorageNoticeMaterials.stream().map(material -> Optional.ofNullable(material.getActualNum()).orElse(BigDecimal.ZERO)) // 提取 quantity 属性
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return reduce;
    }

    @Autowired
    private BussOutboundOrderDetailMapper bussOutboundOrderDetailMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void retract(String id) {
        this.checkRetract(id);
        BussStorageNotice notice = this.getById(id);
        if (notice.getStorageType().equals("1")) {
            this.bussStorageNoticeMaterialMapper.update(null, new LambdaUpdateWrapper<BussStorageNoticeMaterial>()
                    .eq(BussStorageNoticeMaterial::getNoticeId, id).set(BussStorageNoticeMaterial::getQcStatus, 0));
        }
        notice.setStatus("1");
        this.updateById(notice);
        quantityRefund(id);
//		List<BussStorageNoticeMaterialVo> bussStorageNoticeMaterialVos = bussStorageNoticeMaterialMapper.selectByMainId(id);
//		bussStorageNoticeMaterialVos.forEach(item->{
//			item.setStatus(1);
//			bussStorageNoticeMaterialMapper.updateById(item);
//		});
    }

    /**
     * 检查是否允许操作
     *
     * @param id
     */
    public void checkRetract(String id) {
        BussStorageNotice notice = this.getById(id);
        Long aLong1 = bussOutboundOrderDetailMapper.selectCount(new LambdaQueryWrapper<BussOutboundOrderDetail>()
                .eq(BussOutboundOrderDetail::getWarehousingId, id));
        if (aLong1 > 0) {
            throw new RuntimeException("已出库无法操作");
        }
        if (!notice.getStorageType().equals("1")) { //废旧物入库忽略
            Long aLong = this.bussStorageNoticeMaterialMapper.selectCount(new LambdaQueryWrapper<BussStorageNoticeMaterial>().eq(BussStorageNoticeMaterial::getNoticeId, id)
                    .ne(BussStorageNoticeMaterial::getQcStatus, 0));
            if (aLong > 0) {
                throw new RuntimeException("已质检无法操作");
            }
        }
    }


    @Autowired
    private BussInventoryDetailsMapper bussInventoryDetailsMapper;
    @Autowired
    private IBussInventoryDetailsService iBussInventoryDetailsService;

    @Autowired
    private BussInventoryInoutDetailsMapper bussInventoryInoutDetailsMapper;
    @Autowired
    private IBussInventoryInoutDetailsService iBussInventoryInoutDetailsService;


    @Override
    public IPage<StoragePage> queryList(Page<StoragePage> page, QueryWrapper<StoragePage> wrapper) {
        return bussStorageNoticeMapper.queryList(page, wrapper);
    }

    public void quantityRefund(String id) {
        BussStorageNotice notice = bussStorageNoticeMapper.selectById(id);
        //查询入库明细
        List<BussStorageNoticeMaterialVo> details = bussStorageNoticeMaterialMapper.selectByMainId(id);
        //撤销直接删除库存明细
        this.deleteInventoryDetails(id);
        //删除对应的库存入库明细
        bussInventoryInoutDetailsMapper.deleteByBusinessId(id, notice.getCode());

    }

}
